package com.travel.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qianfeng.util.ResultMsg;
import com.travel.entity.TbUser;
import com.travel.exception.LoginAddFailureException;
import com.travel.mapper.UserMapper;
import com.travel.service.UserService;
import com.travel.utils.PhoneCode;
import com.travel.utils.PhoneTools;
import com.travel.utils.TokenTools;
import com.travel.vo.RedisKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, TbUser> implements UserService {

    //注入redis
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    JavaMailSender javaMailSender;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Value("${spring.mail.username}")
    private String from;
    @Value("${source}")
    private String source;

    @Override
    public ResultMsg sendPhone(String phone) {
        PhoneCode.setNewcode();
        String code = Integer.toString(PhoneCode.getNewcode());
        //发短信
        try {
            SendSmsResponse response = PhoneTools.sendSms(phone, code);
            //将response存入redis
            //redis读入
            stringRedisTemplate.boundValueOps(phone).set(code);
            //设置验证码在redis中失效的时间:2分钟
            stringRedisTemplate.boundValueOps(phone).expire(5, TimeUnit.MINUTES);
            return ResultMsg.success(response);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResultMsg sendMail(String mail) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        //从哪里来
        simpleMailMessage.setFrom(from);
        //到哪里去
        simpleMailMessage.setTo(mail);
        //验证码主题
        simpleMailMessage.setSubject("验证码小助手");

        //随机生成验证码范围
        String code = RandomUtil.randomString(source, 4);
        //redis读入
        stringRedisTemplate.boundValueOps(mail).set(code);
        //设置验证码在redis中失效的时间:2分钟
        stringRedisTemplate.boundValueOps(mail).expire(5, TimeUnit.MINUTES);

        //写入文本内容,发给指定邮箱
        simpleMailMessage.setText(code);
        //redis发送到前端
        javaMailSender.send(simpleMailMessage);
        return ResultMsg.success();
    }


    @Override
    public ResultMsg loginByUserNameAndUserPass(String username, String userpass) {

        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        //验证用户名是否存在:mysql
        wrapper.eq("user_name",username);
        wrapper.eq("user_pass",userpass);

        TbUser tbUser = super.getOne(wrapper);
        //弱存在,使用JWT加密
        if (tbUser==null){
            return ResultMsg.error(101,"账号登录失败!");
        }
        //使用JWT加密
        String token = TokenTools.createToken(tbUser.getUserName(), tbUser.getUserPass());
        //使用redis存储token
        String uuid = UUID.randomUUID().toString();
        //头部请求token
        redisTemplate.boundValueOps(RedisKey.LOGIN_USER+uuid).set(token);
        redisTemplate.boundValueOps(RedisKey.LOGIN_USER+uuid).expire(3, TimeUnit.MINUTES);
        //返回token
        return ResultMsg.success(uuid);
    }

    /**
     * 用户注册，添加用户
     * */
    @Override
    public ResultMsg register(TbUser tbUser) {

        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();

        //验证用户名是否唯一:mysql
        wrapper.eq("user_name",tbUser.getUserName());
        TbUser username = super.getOne(wrapper);
        if (username!=null){
            throw new RuntimeException("用户已注册");
        }
        //手机验证
        wrapper=new QueryWrapper<>();
        wrapper.eq("user_tel",tbUser.getUserTel());
        final TbUser usertel = super.getOne(wrapper);
        if (usertel!=null){
            throw new RuntimeException("手机号已注册");
        }
        //验证验证码是否正确:redis中获取key值
        String checkCode1 = stringRedisTemplate.boundValueOps(tbUser.getUserTel()).get();
        //条件:为空或未在redis中获取到key值
        if (checkCode1==null || !checkCode1.equals(tbUser.getUserPCode())){
            throw new RuntimeException("手机验证码有误");
        }

        //邮箱验证
        wrapper = new QueryWrapper<>();
        //验证邮箱是否唯一:mysql
        wrapper.eq("user_mail",tbUser.getUserMail());
        TbUser usermail = super.getOne(wrapper);
        if (usermail!=null){
            throw new RuntimeException("邮箱已注册");
        }
        //验证验证码是否正确:redis中获取key值
        String checkCode2 = stringRedisTemplate.boundValueOps(tbUser.getUserMail()).get();
        //条件:为空或未在redis中获取到key值
        if (checkCode2==null || !checkCode2.equals(tbUser.getUserMCode())){
            throw new RuntimeException("邮箱验证码有误");
        }
        //注册信息入库
        saveOrUpdate(tbUser);
        return ResultMsg.success();
    }

    /**
     * 查询所有用户
     * */
    @Override
    public ResultMsg getAllUser(int current, int size) {
        Page<TbUser> ipage = new Page<>(current,size);
        Page<TbUser> page = super.page(ipage);
        return ResultMsg.success(page);
    }
    /**
     * 通过id查询用户
     * */
    @Override
    public ResultMsg getUserById(int userId) {
        TbUser byId = super.getById(userId);
        if(byId==null){
            return  ResultMsg.error(555,"没有当前的汽车班次");
        }else {
            return ResultMsg.success(byId);
        }
    }
    /**
     * 修改用户
     * */
    @Override
    public ResultMsg updateUser(TbUser tbUser) {
        boolean b = super.saveOrUpdate(tbUser);
        if (tbUser!=null)
            return ResultMsg.success(b);
        else
            return ResultMsg.error(555,"修改汽车票失败");
    }
    /**
     * 添加用户
     * */
    @Override
    public ResultMsg addUser(TbUser tbUser) {
        boolean b = super.saveOrUpdate(tbUser);
        if (tbUser!=null)
            return ResultMsg.success(b);
        else
            return ResultMsg.error(555,"添加汽车票失败");
    }
    /**
     * 删除用户
     * */
    @Override
    public ResultMsg deleteUser(int id) {
        boolean b = super.removeById(id);
        if (b)
            return ResultMsg.success(b);
        return ResultMsg.error(555,"删除失败");
    }
}



